跳到主要内容

30 IIC 触摸驱动实验

在这里插入图片描述

开发板官网https://www.edevkit.com/)

本系列教程目录:


IIC 触摸驱动实验

本章目标:

  • 了解 RA6M5 处理器的 IIC 模块
  • 学会使用 RASC 配置 IIC 模块,使用 API 读写数据。

硬件设计(略,参见配套硬件原理图)

软件设计

新建工程

复制一份“29 SPI_LCD”修改文件夹名“30 IIC_Touch”,双击打开 EBF_RA6M5.uvprojx 工程,通过 Keil 的新建文件新建 i2c_touch.ci2c_touch.h 保存到工程目录下的 src 文件夹中。

FSP 配置

Keil 界面选择 “Tools”→“RA Smart Configurator” 打开 RASC 界面。

根据原理图触摸驱动模块引脚分布,包括一组 I2C 引脚,还需要 TP_RST、TP_INT 两个控制引脚。

配置 I2C 引脚。

插图01

配置 TP_RST 为输出模式,TP_INT 为输入模式。

插图02

添加 I2C Stack 模块。

插图03

配置 I2C Stack 参数。

插图04

配置 I2C 的 DTC 发送接收模块。

插图05

配置完成之后可以按下快捷键 “Ctrl + S” 保存,最后点击 “Generate Project Content” 按钮,让软件自动生成配置代码即可。

程序设计

初始化 IIC 模块,在循环中通过 I2C 读取触摸芯片的数据寄存器,判断是否有触摸点并打印到串口。

  1. 打开 I2C 设备
fsp_err_t R_IIC_MASTER_Open(i2c_master_ctrl_t * const p_ctrl,
i2c_master_cfg_t const * const p_cfg);
  1. 读 I2C 数据
fsp_err_t R_IIC_MASTER_Read(i2c_master_ctrl_t * const p_ctrl,
uint8_t * const p_dest,
uint32_t const bytes,
bool const restart);
  1. 写 I2C 数据
fsp_err_t R_IIC_MASTER_Write(i2c_master_ctrl_t * const p_ctrl,
uint8_t * const p_src,
uint32_t const bytes,
bool const restart);
  1. 设置 I2C 从机地址
fsp_err_t R_IIC_MASTER_SlaveAddressSet(i2c_master_ctrl_t * const p_ctrl,
uint32_t const slave,
i2c_master_addr_mode_t const addr_mode);

程序编写

i2c_touch.h 头文件定义 I2C 初始化、读写函数。

#ifndef BSP_TP_I2C_H
#define BSP_TP_I2C_H

#include "hal_data.h"

typedef struct CSTPOINT
{
uint8_t state;
uint16_t x;
uint16_t y;
uint8_t pressure;
uint8_t num;

} CstPoint;

void CST328_Init(void);

void I2C_ByteWrite(unsigned char address, unsigned char byte);

void I2C_BufferRead(unsigned char* ptr_read,unsigned char address1,unsigned char address2,unsigned char byte);

#endif

i2c_touch.c 中实现读写函数。

#include "i2c_touch.h"

i2c_master_event_t g_i2c_callback_event;
static volatile bool iic_complete = false;

unsigned int timeout_ms = 500;

void CST328_Init(void)
{
fsp_err_t err = FSP_SUCCESS;
err =R_IIC_MASTER_Open(&g_i2c_master0_ctrl, &g_i2c_master0_cfg);
assert(FSP_SUCCESS == err);

R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_06, BSP_IO_LEVEL_HIGH);//rst
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_HIGH);//int
R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);//50ms
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_06, BSP_IO_LEVEL_LOW);//rst
R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);//5ms
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_06, BSP_IO_LEVEL_HIGH);//rst
R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);//200ms
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_HIGH);//int
}

/**
* @brief 以单字节的方式到I2C
* @param
* @arg address:写地址
* @arg byte:写的数据
* @retval 无
*/
void I2C_ByteWrite(unsigned char address, unsigned char byte)
{
iic_complete = false;
unsigned char send_buffer[2] = {};

send_buffer[0] = address;
send_buffer[1] = byte;
R_IIC_MASTER_Write(&g_i2c_master0_ctrl, &send_buffer[0], 2, true); //每当写完数据 false 总线拉高

while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms--;
}
timeout_ms = 500;
}
/**
* @brief 读取I2C
* @param
* @arg ptr_read:读取缓冲区指针
* @arg address:地址
* @arg byte:读取的字节数
* @retval 无
*/
void I2C_BufferRead(unsigned char* ptr_read,unsigned char address1,unsigned char address2,unsigned char byte)
{
unsigned char send_buffer[2] = {};

send_buffer[0] = address1;
send_buffer[1] = address2;
R_IIC_MASTER_Write(&g_i2c_master0_ctrl, &send_buffer[0], 2, true);
while ((I2C_MASTER_EVENT_TX_COMPLETE != g_i2c_callback_event) && timeout_ms)
{
R_BSP_SoftwareDelay(400U, BSP_DELAY_UNITS_MICROSECONDS);
timeout_ms--;
}
timeout_ms = 500;

R_BSP_SoftwareDelay(200U, BSP_DELAY_UNITS_MICROSECONDS);

R_IIC_MASTER_Read(&g_i2c_master0_ctrl, ptr_read, byte, false);

}

void i2c_master_callback(i2c_master_callback_args_t * p_args)
{
(void)(p_args);
}

void cst_read_point(CstPoint *cstPoint)
{
static uint8_t i2cReadBuf[6] = {0};

//读触摸数据
I2C_BufferRead(i2cReadBuf, 0xD0, 0x00, 6);

//判断是否有触摸按下
if( (i2cReadBuf[0] & 0x0f) == 0x06 )
{
cstPoint->state = 1;
}
else
{
cstPoint->state = 0;
}

//获取点x坐标
cstPoint->x = (uint16_t)(((uint16_t)i2cReadBuf[1] << 4) | ((i2cReadBuf[3] & 0xF0) >> 4));
//获取点y坐标
cstPoint->y = (uint16_t)(((uint16_t)i2cReadBuf[2] << 4) | (i2cReadBuf[3] & 0x0F));
//获取点压力
cstPoint->pressure = i2cReadBuf[4];
//获取点个数
cstPoint->num = i2cReadBuf[5];

}

hal_entry.c 文件中添加测试代码。

CstPoint cstPoint;
void hal_entry(void)
{
/* TODO: add your own code here */

led_Init(); // LED 初始化
uart0_Init();

printf("start LCD test\r\n");

//设置白色背景颜色
LCD_Fill(0,0,240,320,0x00);

LCD_6x8Str(0,1, (unsigned char*)"SPI LCD 6x8 string");
LCD_8x16Str(0,2, (unsigned char*)"SPI LCD 8x16 string");

while(1)
{
LED1_TOGGLE();
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒

cst_read_point(&cstPoint);
if(cstPoint.state == 1)
{
printf("point: x=%d, y=%d", cstPoint.x, cstPoint.y);
}
}


#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}

下载验证

连接下载器,将程序编译并下载到开发板之后,按下复位按键来复位开发板,程序启动初始化完。

点击屏幕,检测到触摸点会向串口打印点的 x、y 坐标数据。